package de.mpii.struct.trie;

import java.util.HashMap;
import java.util.Map;

public class Trie<T> {

	public static void main(String[] args) throws Exception {
		// Trie<String> trie = Database.loadClass("artists");

		// System.out
		// .println(trie
		// .extract("John prefers iPhone 4 to iPhone 3GS because he thinks the latter is cool. He is crazy about iPhone 4!"));

		Trie<String> trie = new Trie<String>();

		System.out.println(trie.getSize());
		System.out.println(trie.put("a", "") + ", " + trie.getSize());
		System.out.println(trie.put("ab", "") + ", " + trie.getSize());
		System.out.println(trie.put("b", "") + ", " + trie.getSize());

	}

	private int size = 0;
	private final TrieNode<T> root = new TrieNode<T>(this, null, '\0');

	public Trie() {

	}

	public void enumerate() {
		StringBuilder sbuilder = new StringBuilder();

		root.enumerate(sbuilder, 0);

		System.out.println(sbuilder.toString());
	}

	/**
	 * return a list of longest matched words in the Trie.
	 * 
	 * @param content
	 * @return
	 */
	public Map<String, Integer> extract(String content) {
		Map<String, Integer> words = new HashMap<String, Integer>();

		int endPos;
		String word;

		for (int i = 0; i < content.length(); i++) {

			endPos = root.extract(content, i);

			if (endPos <= 0)
				continue;

			assert endPos > 0 : endPos;
			word = content.substring(i, i + endPos);

			if (!words.containsKey(word))
				words.put(word, 1);
			else
				words.put(word, words.get(word) + 1);
		}

		return words;
	}

	public T get(String key) {
		assert key != null;
		return root.get(key);
	}

	public int getSize() {
		return size;
	}

	public void increaseSize() {
		size++;
	}

	public boolean put(String key, T value) {
		assert key != null;
		return root.put(key, value);
	}
}
